package com.bytedance.touch.view

import android.content.Context
import android.util.AttributeSet

import android.view.MotionEvent
import android.widget.FrameLayout
import com.bytedance.touch.message.ChannelManager
import com.bytedance.touch.message.MsgHelper

class TouchCaptureView(context: Context, attrs: AttributeSet?, defaultStyle: Int):
    FrameLayout(context, attrs, defaultStyle) {

    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0)

    constructor(context: Context): this(context, null)

    private var mMsgHelper: MsgHelper? = null

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (mMsgHelper == null){
            val channel = ChannelManager.INSTANCE.getChannel()
            if (channel != null && channel.isConnect()){
                mMsgHelper = MsgHelper(channel)
            }
        }
        if (mMsgHelper == null){
            return super.dispatchTouchEvent(ev)
        }
        val action = ev.actionMasked
        when(action){
            MotionEvent.ACTION_DOWN,
            MotionEvent.ACTION_UP,
            MotionEvent.ACTION_POINTER_DOWN,
            MotionEvent.ACTION_POINTER_UP,
            MotionEvent.ACTION_CANCEL -> {
                val simpleEvent = transform2SimpleMotionEvent(ev)
                if (simpleEvent != null){
                    mMsgHelper?.sendTouchEvent(simpleEvent)
                }
            }
            MotionEvent.ACTION_MOVE -> {
                val eventList = mutableListOf<SimpleMotionEvent>()
                val count = ev.pointerCount
                for (index in 0 until count){
                    val simpleEvent = transform2SimpleMotionEvent(ev, index)
                    if (simpleEvent != null){
                        eventList.add(simpleEvent)
                    }
                }
                mMsgHelper?.sendTouchEvents(eventList)
            }
        }
        return true
    }

    private fun transform2SimpleMotionEvent(ev: MotionEvent, pointerIndex: Int? = null): SimpleMotionEvent? {
        val action = ev.actionMasked
        val pointId = ev.getPointerId(pointerIndex ?: ev.actionIndex)
        val pointIndex = pointerIndex ?: ev.findPointerIndex(pointId)
        val point = calculatePoint(ev.getX(pointIndex), ev.getY(pointIndex))
        if (point.x < 0 || point.y < 0){
            return null
        }
        return SimpleMotionEvent(
            point.x, point.y,
            action, pointId
        )
    }

    private fun calculatePoint(x: Float, y: Float): FPoint {
        val left: Float = x/measuredWidth
        val top: Float = y/measuredHeight
        return FPoint(left, top)
    }
}

data class SimpleMotionEvent(
    val x: Float,   //
    val y: Float,
    val action: Int,
    val pointerId: Int
)

data class FPoint(
    val x: Float,
    val y: Float
)